package com.jsu.clubmanagementsystem.controller.club;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jsu.clubmanagementsystem.common.BaseResponse;
import com.jsu.clubmanagementsystem.common.DeleteRequest;
import com.jsu.clubmanagementsystem.common.ErrorCode;
import com.jsu.clubmanagementsystem.common.ResultUtils;
import com.jsu.clubmanagementsystem.constant.UserConstant;
import com.jsu.clubmanagementsystem.exception.BusinessException;
import com.jsu.clubmanagementsystem.model.dto.club.ClubAddRequest;
import com.jsu.clubmanagementsystem.model.dto.club.ClubQueryRequest;
import com.jsu.clubmanagementsystem.model.dto.club.ClubUpdateRequest;
import com.jsu.clubmanagementsystem.model.dto.clubmembership.ClubMembershipAddRequest;
import com.jsu.clubmanagementsystem.model.dto.clubmembership.ClubMembershipDeleteRequest;
import com.jsu.clubmanagementsystem.model.entity.*;
import com.jsu.clubmanagementsystem.model.enums.ApplicationTypeEnum;
import com.jsu.clubmanagementsystem.model.enums.ClubMemberRoleEnum;
import com.jsu.clubmanagementsystem.model.enums.ReviewResultEnum;
import com.jsu.clubmanagementsystem.service.activity.ActivityService;
import com.jsu.clubmanagementsystem.service.application.ActivityApplicationService;
import com.jsu.clubmanagementsystem.service.application.ClubApplicationService;
import com.jsu.clubmanagementsystem.service.application.UserApplicationService;
import com.jsu.clubmanagementsystem.service.club.ClubService;
import com.jsu.clubmanagementsystem.service.review.impl.AcceptedReviewProcessor;
import com.jsu.clubmanagementsystem.service.user.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;

@RestController
@Slf4j
public class AdminClubController {

    @Resource
    private ClubService clubService;

    @Resource
    private UserService userService;

    @Resource
    private ActivityService activityService;

    @Resource
    private UserApplicationService userApplicationService;

    @Resource
    private ClubApplicationService clubApplicationService;

    @Resource
    private ActivityApplicationService activityApplicationService;

    @Resource
    private AcceptedReviewProcessor acceptedReviewProcessor;


    /**
     * 增加社团 (管理员)
     * @param addRequest
     * @param request
     * @return
     */
    @PostMapping("/club/add")
    public BaseResponse<Long> addClub(@RequestBody ClubAddRequest addRequest, HttpServletRequest request) {
        if (addRequest == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        if (!userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }

        return ResultUtils.success(clubService.addClub(addRequest));
    }

    /**
     * 删除社团 (管理员)
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @PostMapping("/club/delete")
    public BaseResponse<Boolean> deleteClub(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (!userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }
        Long clubId = deleteRequest.getId();
        Club club = clubService.getById(clubId);
        if (club == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "请求数据不存在");
        }

        List<Activity> activityList = activityService.getActivityListOfClub(clubId);
        if (!activityService.isActivitiesAllEnd(activityList)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "社团仍有活动未结束，无法注销");
        }
        List<UserApplication> applicationList = userApplicationService.getAllApplicationsOfClub(clubId);
        if (!userApplicationService.isApplicationsAllReview(applicationList)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "社团有未审核的申请，无法注销");
        }

        //删除所提交的未审核申请: 修改社团信息、举办活动、修改活动信息
        if (!acceptedReviewProcessor.deleteClubApplicationForDeleteClub(club)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除相关未被审核申请失败");
        }
        if (!acceptedReviewProcessor.deleteActivityApplicationForDeleteClub(club)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除相关未被审核申请失败");
        }

        return ResultUtils.success(clubService.deleteClub(club));
    }

    /**
     * 修改社团信息 (仅管理员)
     * @param updateRequest
     * @param request
     * @return
     */
    @PostMapping("/club/update")
    public BaseResponse<Boolean> updateClub(@RequestBody ClubUpdateRequest updateRequest, HttpServletRequest request) {
        if (updateRequest == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        if (!userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }

        return ResultUtils.success(clubService.updateClub(updateRequest));
    }

    /**
     * 添加成员
     * @param addRequest 添加请求
     * @param request HTTP请求
     * @return 添加结果
     */
    @PostMapping("/club/member/add")
    public BaseResponse<Boolean> addMemberToClub(@RequestBody ClubMembershipAddRequest addRequest, HttpServletRequest request) {
        if (addRequest == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        Long clubId = addRequest.getClubId();
        if (clubId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        User loginUser = userService.getLoginUser(request);
        if (!loginUser.getUserRole().equals(UserConstant.USER_ROLE_ADMIN) &&
                !clubService.isManagerOfClub(loginUser.getId(), clubId)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }

        QueryWrapper<UserApplication> userApplicationQueryWrapper = new QueryWrapper<>();
        userApplicationQueryWrapper.eq("type", ApplicationTypeEnum.JOIN_CLUB.getCode());
        userApplicationQueryWrapper.eq("userId", addRequest.getUserId());
        userApplicationQueryWrapper.eq("result", ReviewResultEnum.WAITING.getCode());
        if (userApplicationService.count(userApplicationQueryWrapper) > 0 &&
                !userApplicationService.remove(userApplicationQueryWrapper)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "处理该用户未被审核的加入社团申请失败");
        }

        ClubMembership membership = new ClubMembership();
        BeanUtils.copyProperties(addRequest, membership);
        if(StringUtils.isBlank(membership.getIdentity())){
            membership.setIdentity(ClubMemberRoleEnum.MEMBER.getInfo()); // 默认为普通成员
        }
        return ResultUtils.success(clubService.addMemberToClub(membership));
    }

    /**
     * 移除成员
     * @param deleteRequest 删除请求
     * @param request HTTP请求
     * @return 删除结果
     */
    @PostMapping("/club/member/delete")
    public BaseResponse<Boolean> deleteMemberFromClub(@RequestBody ClubMembershipDeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        Long clubId = deleteRequest.getClubId();
        if (clubId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        User loginUser = userService.getLoginUser(request);
        if (!loginUser.getUserRole().equals(UserConstant.USER_ROLE_ADMIN) &&
                !clubService.isManagerOfClub(loginUser.getId(), clubId)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }

        QueryWrapper<UserApplication> userApplicationQueryWrapper = new QueryWrapper<>();
        userApplicationQueryWrapper.eq("type", ApplicationTypeEnum.QUIT_CLUB.getCode());
        userApplicationQueryWrapper.eq("userId", deleteRequest.getUserId());
        userApplicationQueryWrapper.eq("result", ReviewResultEnum.WAITING.getCode());
        if (userApplicationService.count(userApplicationQueryWrapper) > 0 &&
                !userApplicationService.remove(userApplicationQueryWrapper)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "处理该用户未被审核的退出社团申请失败");
        }

        ClubMembership membership = new ClubMembership();
        BeanUtils.copyProperties(deleteRequest, membership);
        return ResultUtils.success(clubService.deleteMemberFromClub(membership, false));
    }

    /**
     * 查找社团 (仅管理员)
     * @param clubId
     * @param request
     * @return
     */
    @GetMapping("/club/get")
    public BaseResponse<Club> getClubById(long clubId, HttpServletRequest request){
        if (!userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }
        Club club = clubService.getById(clubId);
        if (club == null) {
            ResultUtils.error(ErrorCode.NOT_FOUND, "目标社团不存在");
        }
        return ResultUtils.success(club);
    }

    /**
     * 查找社团 (仅管理员、分页)
     * @param queryRequest
     * @param request
     * @return
     */
    @PostMapping("/club/list")
    public BaseResponse<Page<Club>> listClubByPage(@RequestBody ClubQueryRequest queryRequest, HttpServletRequest request) {
        if(queryRequest == null){
            throw new BusinessException(ErrorCode.PARAM_ERROR, "参数为空");
        }
        if (!userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }

        QueryWrapper<Club> queryWrapper = clubService.getQueryWrapper(queryRequest);
        int current = queryRequest.getCurrent();
        int pageSize = queryRequest.getPageSize();
        Page<Club> page = clubService.page(new Page<>(current, pageSize), queryWrapper);
        return ResultUtils.success(page);
    }

    /**
     * 获取社团类别及其社团数
     * @param request
     * @return
     */
    @GetMapping("/club/statics/type")
    public BaseResponse<HashMap<String, Integer>> getClubTypeStatics(HttpServletRequest request){
        if (!userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH, "无权限执行此操作");
        }
        return ResultUtils.success(clubService.getClubTypeStatics());
    }
}
